/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.saber.certificacao.modelos;

import br.com.saber.certificacao.enums.Linguagem;
import br.com.saber.certificacao.enums.TipoQuestao;
import br.com.saber.certificacao.modelos.relacionamentos.VersaoQuestao;
import br.com.saber.certificacao.modelos.validadores.interfaces.ValidadoInterface;
import java.util.Set;
import java.util.TreeSet;
import javax.persistence.*;

/**
 *
 * @author gbvbahia
 */
@Entity
@Table(name = "questoes")
public class Questao implements ValidadoInterface, Comparable<Questao> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Long id;

    @Column(name = "contestacoes", nullable = false, unique = false)
    private Integer contestacoes = 0;

    @Column(name = "enunciado", nullable = false, unique = false, length = 2000)
    private String enunciado;

    @Enumerated(EnumType.STRING)
    @Column(name = "linguagem", nullable = false, unique = false, length = 30)
    private Linguagem linguagem;

    @Column(name = "objetivo_certificacao", nullable = false, unique = false, length = 150)
    private String objetivoCertificacao;

    @Column(name = "observacao", nullable = false, unique = false, length = 255)
    private String observacao;

    @Column(name = "status_questao", nullable = false, unique = false)
    private boolean statusQuestao = true;

    @Column(name = "registrada_questao", nullable = false, unique = false)
    private boolean registradosQuestao = true;

    @Enumerated(EnumType.STRING)
    @Column(name = "tipo_questoes", nullable = false, unique = false, length = 30)
    private TipoQuestao tipoQuestao;

    @Lob
    @Column(name="imagem",nullable=true,unique=false)
    private byte[] imagem;
    
    @OneToMany(targetEntity = br.com.saber.certificacao.modelos.relacionamentos.VersaoQuestao.class, 
    mappedBy = "questao", fetch = FetchType.LAZY,cascade=CascadeType.REMOVE)
    private Set<VersaoQuestao> versoesDestaQuestao;

    @OneToMany(targetEntity = br.com.saber.certificacao.modelos.Resposta.class, 
    mappedBy = "questao", fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    private Set<Resposta> respostas;

    @ManyToOne(targetEntity = br.com.saber.certificacao.modelos.Usuario.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "usuario_id", referencedColumnName = "id",nullable=false)
    private Usuario professorResponsavel;

    /**
     * FetchType.EAGER
     * São todas as respostas possíveis desta questão.
     * @return Todas as respostas possíveis da questão.
     */
    public Set<Resposta> getRespostas() {
        if(this.respostas == null) this.respostas = new TreeSet<Resposta>();
        return respostas;
    }

    /**
     * FetchType.EAGER
     * São todas as respostas possíveis desta questão.
     * @param respostas
     */
    public void setRespostas(Set<Resposta> respostas) {
        this.respostas = respostas;
    }

    /**
     * FetchType.LAZY
     * Representa o professor que cadastrou a questão ou fez alguma alteração a mesma.
     * @return O professor responsável pela questão.
     */
    public Usuario getProfessorResponsavel() {
        return professorResponsavel;
    }

    /**
     * FetchType.LAZY
     * Representa o professor que cadastrou a questão ou fez alguma alteração a mesma.
     * @param professorResponsavel
     */
    public void setProfessorResponsavel(Usuario professorResponsavel) {
        this.professorResponsavel = professorResponsavel;
    }

    /**
     * fetch=FetchType.LAZY
     * Representa todas as versões que esta versão pode ser inserida.
     * @return Todas as versões em que essa questão pode ser inserida.
     */
    public Set<VersaoQuestao> getVersoesDestaQuestao() {
        if (this.versoesDestaQuestao == null) {
            this.versoesDestaQuestao = new TreeSet<VersaoQuestao>();
        }
        return versoesDestaQuestao;
    }

    /**
     * fetch=FetchType.LAZY
     * Representa todas as versões que esta versão pode ser inserida.
     * @param versoesDestaQuestao
     */
    public void setVersoesDestaQuestao(Set<VersaoQuestao> versoesDestaQuestao) {
        this.versoesDestaQuestao = versoesDestaQuestao;
    }

    public Integer getContestacoes() {
        return contestacoes;
    }

    public void setContestacoes(Integer contestacoes) {
        this.contestacoes = contestacoes;
    }

    public String getEnunciado() {
        return enunciado;
    }

    public void setEnunciado(String enunciado) {
        this.enunciado = enunciado;
    }

    public Linguagem getLinguagem() {
        return linguagem;
    }

    public void setLinguagem(Linguagem linguagem) {
        this.linguagem = linguagem;
    }

    public String getObjetivoCertificacao() {
        return objetivoCertificacao;
    }

    public void setObjetivoCertificacao(String objetivoCertificacao) {
        this.objetivoCertificacao = objetivoCertificacao;
    }

    public String getObservacao() {
        return observacao;
    }

    public void setObservacao(String observacao) {
        this.observacao = observacao;
    }

    public boolean isStatusQuestao() {
        return statusQuestao;
    }

    public void setStatusQuestao(boolean statusQuestao) {
        this.statusQuestao = statusQuestao;
    }

    public TipoQuestao getTipoQuestao() {
        return tipoQuestao;
    }

    public void setTipoQuestao(TipoQuestao tipoQuestao) {
        this.tipoQuestao = tipoQuestao;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public boolean isRegistradosQuestao() {
        return registradosQuestao;
    }

    public void setRegistradosQuestao(boolean registradosQuestao) {
        this.registradosQuestao = registradosQuestao;
    }

    public byte[] getImagem() {
        return imagem;
    }

    public void setImagem(byte[] imagem) {
        this.imagem = imagem;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Questao)) {
            return false;
        }
        Questao other = (Questao) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.saber.certificacao.modelos.Questao[id=" + id + "]";
    }

    @Override
    public int compareTo(Questao o) {
        int toReturn = 0;
        //int toReturn = this.enunciado.compareTo(o.getEnunciado());
        if(toReturn == 0){
            toReturn = this.id.compareTo(o.getId());
        }
        return toReturn;
    }

    /**
     * As versões são Lazy, utilize somente se tiver certeza de ter carregado
     * a coleção de versão.
     * @return String no romato [versaoNome,versaoNome]
     */
    public String getVersoesString(){
        String toReturn = "";
        for(VersaoQuestao vq: getVersoesDestaQuestao()){
            if(toReturn.equals(""))
                toReturn = vq.getVersao().getNome();
            else
                toReturn += ", "+vq.getVersao().getNome();
        }
        return "[" + toReturn + "]";
    }
}
